/**
 @file

 @date 2010/02/22

 @version v5.1

 This file contains those macro & enum definitions and global var
*/

#ifndef _DRV_COMMON_H_
#define _DRV_COMMON_H_

#include "drv_api.h"
#include "drv_ser.h"
/*AT_TODO*/
struct drv_addr_ext_field_s
{
    uint32 dp   :2;
    uint32 pp   :4;
    uint32 core :2;
    uint32 resv :24;
};
typedef struct drv_addr_ext_field_s drv_addr_ext_field_t;
union drv_addr_ext_u
{
    drv_addr_ext_field_t field;
    uint32 value;
};
typedef union drv_addr_ext_u drv_addr_ext_t;
union drv_index_ext_u
{
    struct
    {
        uint32 index32;
        drv_addr_ext_t addr;
    }ext;
    uint64 value;
};
typedef union drv_index_ext_u drv_index_ext_t;

#define DRV_WB_VERSION(V_Release, V_Build)  (((V_Release)<<16)|V_Build)
#define DRV_WB_R_VERSION(V)                         (((V)&0xFFFF0000)>>16)
#define DRV_WB_B_VERSION(V)                         ((V)&0x0000FFFF)

#define DRV_WB_VERSION_CHECK(version, wb_version)\
    (DRV_WB_R_VERSION(version) != DRV_WB_R_VERSION(wb_version))
#define DRV_WB_VERSION_SDB                  DRV_WB_VERSION(1,0)

#define DRV_INVALID_FIELD_ID    0xFFFFFFFF
#define DRV_CMD_TIMEOUT   0x6400

#if(SDK_WORK_PLATFORM == 1)
#define DRV_APP_LOOP_CNT 20000
extern uint16 g_mem_fib_hashkey_cutdown;
extern uint8 g_drv_vchip_mode;
#else
#ifdef EMULATION_ENV
#define DRV_APP_LOOP_CNT 50000
#else
#define DRV_APP_LOOP_CNT 2000
#endif
#endif

#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
extern uint8 g_drv_lchip_2_pp[8];
extern uint8 g_drv_lchip_2_core[8];
#define DRV_LCHIP_2_PP(lchip) (g_drv_lchip_2_pp[lchip - drv_vchip_pp_base[lchip]])
#define DRV_LCHIP_2_CORE(lchip) (g_drv_lchip_2_core[lchip - drv_vchip_pp_base[lchip]])
#else
#define DRV_LCHIP_2_PP(lchip) (g_drv_chip[lchip].pp_id)
#define DRV_LCHIP_2_CORE(lchip) (g_drv_chip[lchip].core_id)
#endif

#define HASH_KEY_LENGTH_MODE_SINGLE      0
#define HASH_KEY_LENGTH_MODE_DOUBLE      1
#define HASH_KEY_LENGTH_MODE_QUAD        2

#define SINGLE_KEY_BYTE       12      /*sizeof(DsFibHost0MacHashKey_m) */
#define DOUBLE_KEY_BYTE       24    /*sizeof(DsFibHost0Ipv6UcastHashKey_m) */
#define QUAD_KEY_BYTE          48     /*sizeof(DsFibHost0HashCam_m) */
#define DS_USER_ID_HASH_CAM_BYTES  48 /*sizeof(DsUserIdHashCam_m) */

#define DRV_ADDR_CORE_EN(ADDR) (uint64)((((uint64)0x1 << DRV_LCHIP_2_CORE(lchip)) << 38)  | (ADDR))
#define DRV_ADDR_PP_EN(ADDR) (uint64)((((uint64)0x1 << DRV_LCHIP_2_CORE(lchip)) << 38) | (((uint64)0x1 << DRV_LCHIP_2_PP(lchip)) << 34) | (ADDR))
#define DRV_ADDR_DP_EN(ADDR, DPID) (uint64)((((uint64)0x1 << DRV_LCHIP_2_CORE(lchip)) << 38) | (((uint64)0x1 << DRV_LCHIP_2_PP(lchip)) << 34) | (((uint64)0x1 << (DPID)) << 32) | (ADDR))
#define DRV_DP_BMP_START     0
#define DRV_PP_BMP_START     2
#define DRV_CORE_BMP_START   6

enum drv_acc_chip_type_e
{
    DRV_ACC_CHIP_MAC_WRITE_BY_INDEX,       /*0*/
    DRV_ACC_CHIP_MAC_WRITE_BY_KEY,         /*1*/
    DRV_ACC_CHIP_MAC_DEL_BY_INDEX,         /*2*/
    DRV_ACC_CHIP_MAC_DEL_BY_KEY,           /*3*/
    DRV_ACC_CHIP_MAC_FLUSH_BY_PORT_VLAN,   /*4*/
    DRV_ACC_CHIP_MAC_FLUSH_DUMP_BY_ALL,    /*5*/
    DRV_ACC_CHIP_MAC_LOOKUP_BY_KEY,        /*6*/
    DRV_ACC_CHIP_HOST0_lOOKUP_BY_KEY,      /*7*/
    DRV_ACC_CHIP_HOST0_lOOKUP_BY_INDEX,    /*8*/
    DRV_ACC_CHIP_HOST0_WRITE_BY_INDEX,     /*9*/
    DRV_ACC_CHIP_HOST0_WRITE_BY_KEY,       /*10*/
    DRV_ACC_CHIP_LIMIT_UPDATE,             /*11*/
    DRV_ACC_CHIP_LIMIT_READ,               /*12*/
    DRV_ACC_CHIP_LIMIT_WRITE,              /*13*/
    DRV_ACC_CHIP_MAC_FLUSH_BY_MAC_PORT,    /*14*/
    DRV_ACC_CHIP_MAC_DUMP_BY_PORT_VLAN,    /*15*/
    DRV_ACC_CHIP_WRITE_DSMAC,              /*16*/
    DRV_ACC_CHIP_WRITE_DSAGING,            /*17*/
    DRV_ACC_CHIP_MAC_FLUSH_CACHE = 0x1E,   /*30*/
    DRV_ACC_CHIP_MAC_FLUSH_DUMP_BY_FLEX = 0x1F, /*31*/
    DRV_ACC_CHIP_MAX_TYPE
};
typedef enum drv_acc_chip_type_e drv_acc_chip_type_t;

#if 0
#define DRV_DBG_INFO(FMT, ...)   sal_printf(FMT, ##__VA_ARGS__); 
#define DRV_DBG_FUNC()    sal_printf("\n%s()\n", __FUNCTION__);
 #else
#define DRV_DBG_INFO(FMT, ...)
#define DRV_DBG_FUNC()
 #endif
 #define DRV_DUMP_INFO(FMT, ...) sal_printf(FMT, ##__VA_ARGS__); 

//Cmodel Modify
#ifdef ARCTIC

#define MAX_IGR_SCL_TCAM0_NUM   2
#define MAX_IGR_SCL_TCAM1_NUM   2
#define MAX_IGR_ACL_TCAM_NUM   24
#define MAX_EGR_ACL_TCAM_NUM    12
#define MAX_EGR_SCL_TCAM_NUM    2
#define MAX_NOR_TCAM_NUM        (MAX_IGR_SCL_TCAM0_NUM + MAX_IGR_SCL_TCAM1_NUM + MAX_IGR_ACL_TCAM_NUM + MAX_EGR_SCL_TCAM_NUM + MAX_EGR_ACL_TCAM_NUM)
#define OAM_HASH_CAM_NUM           ( DRV_CONST(DRV_OAM_HASH_CAM_NUM) )
#define OAM_RMEP_HASH_CAM_NUM      ( 32 )
#define EGRESS_SCL_HASH_CAM_NUM    ( 0 )
#else
#define MAX_IGR_SCL_TCAM0_NUM   2
#define MAX_IGR_SCL_TCAM1_NUM   2
#define MAX_IGR_ACL_TCAM_NUM   16
#define MAX_EGR_ACL_TCAM_NUM    4
#define MAX_EGR_SCL_TCAM_NUM    2
#define MAX_NOR_TCAM_NUM        (MAX_IGR_SCL_TCAM0_NUM + MAX_IGR_SCL_TCAM1_NUM + MAX_IGR_ACL_TCAM_NUM + MAX_EGR_SCL_TCAM_NUM + MAX_EGR_ACL_TCAM_NUM)

#define OAM_HASH_CAM_NUM           ( 64 )
#define OAM_RMEP_HASH_CAM_NUM      ( 32 )
#define EGRESS_SCL_HASH_CAM_NUM    ( 0 )
#endif



#define TABLE_SDB_ADDR_IDX  3
#define ADDR_NUM            4
#define TABLE_SDB_ADDR_NUM  1

//#ifdef
//typedef uint32 ds_t[32];

#define DRV_UINT32_BITS  32
#define _DRV_BMP_OP(_bmp, _offset, _op)     \
    (_bmp[(_offset) / DRV_UINT32_BITS] _op(1U << ((_offset) % DRV_UINT32_BITS)))

#define DRV_BMP_ISSET(bmp, offset)          \
    _DRV_BMP_OP((bmp), (offset), &)
#define DRV_BMP_SET(bmp, offset)            \
    _DRV_BMP_OP((bmp), (offset), |= )
#define DRV_BMP_UNSET(bmp, offset)          \
    _DRV_BMP_OP((bmp), (offset), &= ~)
#define DRV_BMP_BITS(bmp)                   \
    ((DRV_UINT32_BITS * sizeof((bmp)) / sizeof(uint32)))
#define DRV_BMP_ITER_BEGIN(bmp, offset)                             \
    do {                                                                \
        for ((offset) = 0; (offset) < DRV_BMP_BITS((bmp)); (offset)++)  \
            if (DRV_BMP_ISSET((bmp), (offset)))
#define DRV_BMP_ITER_END(bmp, offset)       \
    } while (0)

#define cosim  0
#define DRV_MAX_ARRAY_NUM 256
#define MAX_WORD_LEN  20
#define MAX_HASH_LEVEL 10

#define DRV_WB_STATUS_DONE          1
#define DRV_WB_STATUS_RELOADING     2
#define DRV_WB_STATUS_SYNC          3

#define DRV_I2C_REQ_READ     0x80
#define DRV_I2C_REQ_WRITE    0x0
#define DRV_I2C_WRDATA_OFFSET  0
#define DRV_I2C_ADDRCMD_OFFSET 4
#define DRV_I2C_RDDATA_OFFSET 5
#define DRV_I2C_STATUS_OFFSET 9

#define DRV_INIT_CHECK(lchip) \
    do { \
        if (lchip >= DRV_MAX_CHIP_NUM || !p_drv_master[lchip] || !p_drv_master[lchip]->init_done){ \
            return DRV_E_NOT_INIT; } \
    } while (0)

#define DRV_LCHIP_CHECK_GOTO(lchip, label, ret) \
    do { \
        if (lchip >= DRV_MAX_CHIP_NUM || !p_drv_master[lchip] || !p_drv_master[lchip]->init_done){ \
            ret = DRV_E_NOT_INIT; goto label;} \
    } while (0)

#define LPM_TCAM_TCAM_MEM_BYTES                                      16
#define FLOW_TCAM_TCAM_MEM_BYTES                                     28
#define Q_MGR_ENQ_TCAM_MEM_BYTES                                     28
#define IPE_CID_TCAM_MEM_BYTES                                       8

typedef uint32 field_array_t[DRV_MAX_ARRAY_NUM];
typedef unsigned long addrs_t;

/*max tcam_mem size : 13*/
typedef uint32 drv_ds_t[16];

#define DRV_GPORT_TO_GCHIP(gport)        (((gport) >> 9) & 0x7f)
#define DRV_GPORT_TO_LPORT(gport)        ((gport) & 0x1ff)

#ifndef PACKET_TX_USE_SPINLOCK
#define DRV_PCI_LOCK(lchip_offset)          sal_mutex_lock(p_drv_master[lchip_offset]->p_pci_mutex)
#define DRV_PCI_UNLOCK(lchip_offset)        sal_mutex_unlock(p_drv_master[lchip_offset]->p_pci_mutex)
#define DRV_I2C_LOCK(lchip_offset)          sal_mutex_lock(p_drv_master[lchip_offset]->p_i2c_mutex)
#define DRV_I2C_UNLOCK(lchip_offset)        sal_mutex_unlock(p_drv_master[lchip_offset]->p_i2c_mutex)
#define DRV_MMAP_LOCK(lchip_offset)          sal_mutex_lock(p_drv_master[lchip_offset]->p_mmap_mutex)
#define DRV_MMAP_UNLOCK(lchip_offset)        sal_mutex_unlock(p_drv_master[lchip_offset]->p_mmap_mutex)
#else
#define DRV_PCI_LOCK(lchip_offset)          sal_spinlock_lock((sal_spinlock_t*)p_drv_master[lchip_offset]->p_pci_mutex)
#define DRV_PCI_UNLOCK(lchip_offset)        sal_spinlock_unlock((sal_spinlock_t*)p_drv_master[lchip_offset]->p_pci_mutex)
#define DRV_I2C_LOCK(lchip_offset)          sal_spinlock_lock((sal_spinlock_t*)p_drv_master[lchip_offset]->p_i2c_mutex)
#define DRV_I2C_UNLOCK(lchip_offset)        sal_spinlock_unlock((sal_spinlock_t*)p_drv_master[lchip_offset]->p_i2c_mutex)
#define DRV_MMAP_LOCK(lchip_offset)          sal_spinlock_lock((sal_spinlock_t*)p_drv_master[lchip_offset]->p_mmap_mutex)
#define DRV_MMAP_UNLOCK(lchip_offset)        sal_spinlock_unlock((sal_spinlock_t*)p_drv_master[lchip_offset]->p_mmap_mutex)
#endif

#define DRV_TBL_DYNAMIC(lchip, tbl_id) ((NULL != TABLE_EXT_INFO_PTR(lchip, tbl_id)) && (DRV_TABLE_TYPE_DYNAMIC == TABLE_EXT_INFO_TYPE(lchip, tbl_id)))

/* table extended property type */
enum ext_content_type_s
{
    EXT_INFO_TYPE_NORMAL = 0,
    EXT_INFO_TYPE_TCAM,
    EXT_INFO_TYPE_TCAM_AD,
    EXT_INFO_TYPE_TCAM_LPM_AD, /*SDK Modify*/
    EXT_INFO_TYPE_TCAM_NAT_AD, /*SDK Modify*/
    EXT_INFO_TYPE_LPM_TCAM_IP,
    EXT_INFO_TYPE_LPM_TCAM_NAT,
    EXT_INFO_TYPE_STATIC_TCAM_KEY,
    EXT_INFO_TYPE_DESC,
    EXT_INFO_TYPE_DBG,
    EXT_INFO_TYPE_DYNAMIC,
    EXT_INFO_TYPE_MIXED,
    EXT_INFO_TYPE_INVALID,
};
typedef enum ext_content_type_s ext_content_type_t;

enum drv_tbl_type_s
{
    DRV_TBL_TYPE_NORMAL,
    DRV_TBL_TYPE_DYN,   /* dynamic op without mask */
    DRV_TBL_TYPE_CHA_MAP,
    DRV_TBL_TYPE_HOOK, /*AT, IpeFwdCtl*/
    DRV_TBL_TYPE_DYN_MASK,
    DRV_TBL_TYPE_DYN_LPM,
    DRV_TBL_TYPE_TCAM,
    DRV_TBL_TYPE_OAM,
    DRV_TBL_TYPE_APS_MASK,
    DRV_TBL_TYPE_MAC,
    DRV_TBL_TYPE_MCU,
    DRV_TBL_TYPE_MET_SLIM,/*AT, for dsmet slim*/
    DRV_TBL_TYPE_RTC,/*AT, ts engine*/
    DRV_TBL_TYPE_M_CORE, /*AT, MULTI Core*/
    DRV_TBL_TYPE_MAX,
};
typedef enum drv_tbl_type_s drv_tbl_type_t;

/* Unified tables extended property structure */
struct tbls_ext_info_s
{
    uint32 ext_content_type;
    void *ptr_ext_content;
    uint8 ext_type;     /*used to identify special table: 0-normal, 1-parser table, 2-80bits flow ad table*/
    struct tbls_ext_info_s *ptr_next;
};
typedef struct tbls_ext_info_s tbls_ext_info_t;

typedef struct tables_info_s {
        uint32 slicetype : 5;
        uint32 optype    : 4;
        uint32 entry     : 21;  /* table entry num */
        uint32 rsv1      : 2;

        uint32 byte      : 12;  /* entry size */
        uint32 sdb_type  : 2;   /* 0-Disable, 1-Performance, 2-ALL */
        uint32 sdb_read  : 1;   /* 0-Disable, 1-Enable read */
        uint32 bus       : 1;
        uint32 stats     : 1;
        uint32 addr_num  : 10;
        uint32 tbl_type  : 5; /* drv_tbl_type_t */


        uint32 field_num : 20;/*AT_TODO*/
        uint32 entry_offset : 12;

        uint32 tcam_mem     : 1;
        uint32 fea_mod      : 5;   /* ref to DRV_FEATURE_MODE_XXX */
        uint32 tbl_id       : 16;
        uint32 rsv          :10;

        addrs_t *addrs;
        fields_t *ptr_fields;
}tables_info_t;

typedef struct tables_name_s {
        char *ptr_mod_name;
        char *ptr_tbl_name;
        fields_name_t* fields_name;
}tables_name_t;

typedef struct tables_ext_info_s {
    int32 entry;
    addrs_t addrs[3];
    tbls_ext_info_t* ptr_ext_info;    /*refer to CTC_MAX_LOCAL_CHIP_NUM*/
}tables_ext_info_t;

typedef struct drv_mem_s {
    uint32 entry_num;
    uint32 addr_3w;
    uint32 addr_6w;
    uint32 addr_12w;
    uint32 type;
    uint32 sub_type;
    uint32 sub_id       :8;
    uint32 tcam_map_id  :8;
    uint32 couple_mode  :1;
    uint32 entry_size   :8;    /*for ecc use*/
    uint32 addr_sel     :2;
    uint32 ext_type     :1; /*for mpls hash table*/
    uint32 rsv          :4;
    uint16* index_map;
} drv_mem_t;

#define SDK_COSIM 0

/* All the following asic mem base is not determined, shall refer to asic design */
#define DRV_MEM_INFO(lchip, mem_id)         (p_drv_master[lchip]->p_mem_info[mem_id])
#define DRV_MEM_ENTRY_NUM(lchip, mem_id)   (DRV_MEM_INFO(lchip, mem_id).entry_num)
#define DRV_MEM_ADD3W(lchip, mem_id)   (DRV_MEM_INFO(lchip, mem_id).addr_3w)
#define DRV_MEM_ADD6W(lchip, mem_id)   (DRV_MEM_INFO(lchip, mem_id).addr_6w)
#define DRV_MEM_ADD12W(lchip, mem_id)   (DRV_MEM_INFO(lchip, mem_id).addr_12w)
#define DRV_MEM_COUPLE(lchip, mem_id)   (DRV_MEM_INFO(lchip, mem_id).couple_mode)
#define DRV_MEM_ENTRY_SIZE(lchip, mem_id)   (DRV_MEM_INFO(lchip, mem_id).entry_size)
#define DRV_MEM_EXT_TYPE(lchip, mem_id) (DRV_MEM_INFO(lchip, mem_id).ext_type)
#define DRV_TCAM_MAP(lchip, map_id)     (p_drv_master[lchip]->p_tcam_map[map_id])

#define MAX_MEMORY_BLOCK_NUM DRV_FTM_EDRAM_MAX
#define MAX_MIXED_MEMORY_BLOCK_NUM 3
#define MAX_DYNAMIC_MEMORY_BLOCK_NUM (MAX_MEMORY_BLOCK_NUM - MAX_MIXED_MEMORY_BLOCK_NUM)
#define MAX_DRV_BLOCK_NUM (MAX_MEMORY_BLOCK_NUM)
#define ADDR_OFFSET 3
#define MAX_LPM_TCAM_NUM    6
#define MAX_D2_LPM_TCAM_NUM    12
#define MAX_STATIC_TCAM_NUM 2
#define MAX_DRV_TCAM_BLOCK_NUM (MAX_NOR_TCAM_NUM + MAX_LPM_TCAM_NUM)
#define USERID_TCAM_MAX_NUM 6
#define TCAM_BITMAP_MAX_NUM 9
#define LPM_TCAM_BITMAP_MAX_NUM 12

/* All the following asic mem base is not determined, shall refer to asic design */

/* ds_sdb_mode */
#define SDB_DIS     0
#define SDB_PERF    1
#define SDB_ALL     2

enum ds_slice_type_e
{
    SLICE_Share = 0,
    SLICE_Duplicated,
    SLICE_Cascade,
    SLICE_PreCascade,
    SLICE_Default,
	SLICE_Cascade_Share_None,
    SLICE_Default_Share_None,
    SLICE_Cascade_Cascade_None,
    SLICE_Duplicated_Share_None,
    SLICE_Duplicated_Duplicated_None,
    SLICE_Cascade_Cascade_Cascade,
    SLICE_Default_Default_None,
    SLICE_Duplicated_Duplicated_Duplicated,
    SLICE_Cascade_Duplicated_None,
    SLICE_Cascade_PreCascade_None,
    SLICE_Default_Default_Duplicated,
    SLICE_Duplicated_Duplicated_Cascade,

    Default_Default_None,
    Default_Default_Cascade,
    Duplicated_Duplicated_None,
    Cascade_Cascade_None,
    Default_Default_Duplicated
};
typedef enum ds_slice_type_e ds_slice_type_t;

enum ds_mem_type_e
{
   MEM_TYPE_PER_DP,
   MEM_TYPE_PER_PP,
   MEM_TYPE_PER_CORE,
   MEM_TYPE_PEER_DP,
   MEM_TYPE_PEER_PP,
   MEM_TYPE_PER_MAX
};
typedef enum ds_mem_type_e ds_mem_type_t;

typedef enum ds_op_type {
    Op_Default = 1,
    Op_ReadMux = 2,
    Op_DisBurst = 4,
    Op_DisWriteMask = 8,
} ds_op_type_t;

enum dup_address_offset_type_e
{
    SLICE_Addr_All,
    SLICE_Addr_0,
    SLICE_Addr_1,
    SLICE_Addr_Invalid,
};
typedef enum dup_address_offset_type_e dup_address_offset_type_t;

#define DRV_IS_BIT_SET(flag, bit)   (((flag) & (1 << (bit))) ? 1 : 0)
#define DRV_BIT_SET(flag, bit)      ((flag) = (flag) | (1 << (bit)))
#define DRV_BIT_UNSET(flag, bit)      ((flag) = (flag) & (~(1 << (bit))))

/**
 @brief check whether the operation's return value is error or not
*/
extern int32 g_error_on;
#define DRV_IF_ERROR_RETURN(op) \
do\
{ \
    int32 rv; \
    if ((rv = (op)) < 0) \
    { \
      if (g_error_on) \
      DRV_DUMP_INFO("Error Happened!! Fun:%s()  Line:%d ret:%d\n",__FUNCTION__,__LINE__, rv); \
        return(rv); \
    }\
}\
while(0)

#define DRV_IF_ERROR_GOTO(op, ret, label) \
do \
{ \
    if ((ret = (op)) < 0) \
    { \
        goto label; \
    } \
} \
while(0)
/**
 @brief check whether the operation's return value is error or not. If error, then unlock
*/
#define DRV_IF_ERROR_RETURN_WITH_UNLOCK(op, lock) \
    { \
        int32 rv; \
        if ((rv = (op)) < 0)  \
        {  \
            sal_mutex_unlock(lock); \
            return rv; \
        } \
    }

/**
 @brief define the pointer valid check
*/
#define DRV_PTR_VALID_CHECK(ptr)\
if (NULL == (ptr))\
{\
    return DRV_E_INVALID_PTR;\
}

#define SHIFT_LEFT_MINUS_ONE(bits)    ( ((bits) < 32) ? ((1 << (bits)) - 1) : -1)


struct tcam_alloc_info_s
{
    uint32 tcam_mem_bitmap[DRV_FTM_TCAM_KEYM/32+1];                  /* bitmap indicate table in which tcam memory block */
    uint32 tcam_mem_hw_data_base[MAX_DRV_TCAM_BLOCK_NUM][ADDR_OFFSET];  /* hw_data_base per memory block */
    uint32 tcam_mem_hw_mask_base[MAX_DRV_TCAM_BLOCK_NUM][ADDR_OFFSET];  /* hw_data_base per memory block */
    uint32 tcam_mem_entry_num[MAX_DRV_TCAM_BLOCK_NUM];                  /* enter num in per memory block, per 80 bit */
    uint32 tcam_mem_entry_offset[MAX_DRV_TCAM_BLOCK_NUM];               /* enter num offset in per memory block, per 80 bit */
    uint32 tcam_mem_entry_start_index[MAX_DRV_TCAM_BLOCK_NUM];          /* global table start index in per memory block */
    uint32 tcam_mem_entry_end_index[MAX_DRV_TCAM_BLOCK_NUM];            /* global table end index in per memory bloci */
    uint32 tcam_mem_sw_data_base[MAX_DRV_TCAM_BLOCK_NUM];               /* TMM hw_data_base per memory block */
    uint32 tcam_mem_lpmlkp2_entry_num;                                  /* TMM lpm lookup2 entry num */

    uint32 block_id[MAX_DRV_TCAM_BLOCK_NUM];
    uint32 start_index[MAX_DRV_TCAM_BLOCK_NUM];
    uint32 end_index[MAX_DRV_TCAM_BLOCK_NUM];
    uint32 block_num;

};
typedef struct tcam_alloc_info_s tcam_alloc_info_t;

struct tcam_mem_ext_content_s
{
    addrs_t *hw_mask_base;
    uint32 key_size :8;
    uint32 tcam_type:5;
    uint32 tcam_module:5;
    uint32 drv_tcam_type:5;
    uint32 lpm_type:2;
    uint32 rsv:7;

    /*now use 3*/
    uint8 blk_id[4];


    tcam_alloc_info_t tcam_alloc_info;
};
typedef struct tcam_mem_ext_content_s tcam_mem_ext_content_t;

#define DYNAMIC_ACCESS_MEM_SIZE_SHIFT                         0
#define DYNAMIC_ACCESS_UNIT_NUM_SHIFT                         8
#define DYNAMIC_ACCESS_UNIT_SIZE_SHIFT                        16

/* dynamic tbl extended property structure */
enum dynamic_mem_access_mode_u
{
    DYNAMIC_DEFAULT          = 0,
    DYNAMIC_1W_MODE          = 1,
    DYNAMIC_2W_MODE          = 2,
    DYNAMIC_3W_MODE          = 3,
    DYNAMIC_4W_MODE          = 4,
    DYNAMIC_6W_MODE          = 6,
    DYNAMIC_8W_MODE          = 8,
    DYNAMIC_9W_MODE          = 9,
    DYNAMIC_12W_MODE         = 12,
    DYNAMIC_16W_MODE         = 16,
    DYNAMIC_20W_MODE         = 20,

    DYNAMIC_1W8U_12W_MODE    = (1<<DYNAMIC_ACCESS_UNIT_SIZE_SHIFT) | (8<<DYNAMIC_ACCESS_UNIT_NUM_SHIFT) | DYNAMIC_12W_MODE,
    DYNAMIC_2U_4W_MODE       = (2<<DYNAMIC_ACCESS_UNIT_NUM_SHIFT) | DYNAMIC_4W_MODE,
    DYNAMIC_2U_8W_MODE       = (2<<DYNAMIC_ACCESS_UNIT_NUM_SHIFT) | DYNAMIC_8W_MODE,
    DYNAMIC_4U_12W_MODE      = (4<<DYNAMIC_ACCESS_UNIT_NUM_SHIFT) | DYNAMIC_12W_MODE,
    DYNAMIC_4U_16W_MODE      = (4<<DYNAMIC_ACCESS_UNIT_NUM_SHIFT) | DYNAMIC_16W_MODE,
    DYNAMIC_4U_20W_MODE      = (4<<DYNAMIC_ACCESS_UNIT_NUM_SHIFT) | DYNAMIC_20W_MODE,

    DYNAMIC_INVALID
};
typedef enum dynamic_mem_access_mode_u dynamic_mem_access_mode_t;

struct dynamic_mem_allocate_info_s
{
    uint32 dynamic_mem_bitmap[MAX_DRV_BLOCK_NUM/32+1];                                          /* bitmap indicate table in which dynamic memory block */
    uint32 dynamic_mem_hw_data_base[MAX_DRV_BLOCK_NUM][ADDR_OFFSET];    /* hw_data_base per memory block */
    uint32 dynamic_mem_entry_num[MAX_DRV_BLOCK_NUM];                    /* enter num in per memory block, per 80 bit */
    uint32 dynamic_mem_entry_start_index[MAX_DRV_BLOCK_NUM];            /* global table start index in per memory block */
    uint32 dynamic_mem_entry_end_index[MAX_DRV_BLOCK_NUM];              /* global table end index in per memory block*/
    uint32 dynamic_mem_block_offset[MAX_DRV_BLOCK_NUM];                 /* local offset in per memory block*/

    uint32 block_id[MAX_DRV_BLOCK_NUM];
    uint32 start_index[MAX_DRV_BLOCK_NUM];
    uint32 end_index[MAX_DRV_BLOCK_NUM];
    uint8  block_num;
    uint8  unit_num; /* mem_size/unit_size   */
    uint8  unit_size; /* The table size (160 bit) of the table in the dynamic memory*/
    uint8  mem_size; /* example: A dynamic memory is aligned according to 640 bit,but the memory contains various entries of 160/320/480/640 bit.
                     and the memory size is 640 bit (32 word)*/
};
typedef struct dynamic_mem_allocate_info_s dynamic_mem_allocate_info_t;

struct dynamic_mem_ext_content_s
{
    dynamic_mem_allocate_info_t dynamic_mem_allocate_info;  /* store memory allocated info of table in which block */
    dynamic_mem_access_mode_t dynamic_access_mode;          /* access mode, indicate how to explain one index of table */
};
typedef struct dynamic_mem_ext_content_s dynamic_mem_ext_content_t;


#define TCAM_TYPE_EXT (tcam_mem_ext_content_t *)
#define DYNAMIC_TYPE_EXT (dynamic_mem_ext_content_t *)

/* Define get Memory infomation operation */
#define TABLE_INFO_PTR(lchip, tbl_id)             (&p_drv_master[lchip]->p_tbl_info[p_drv_master[lchip]->p_tbl_mapping[tbl_id]])
#define TABLE_INFO(lchip, tbl_id)                 (p_drv_master[lchip]->p_tbl_info[p_drv_master[lchip]->p_tbl_mapping[tbl_id]])
#define MODULE_NAME(lchip, tbl_id)                (p_drv_master[lchip]->p_tbl_name[p_drv_master[lchip]->p_tbl_mapping[tbl_id]].ptr_mod_name)
#define TABLE_STATS(lchip, tbl_id)                (TABLE_INFO(lchip, tbl_id).stats)
#define TABLE_BUS(lchip, tbl_id)                  (TABLE_INFO(lchip, tbl_id).bus)
#define TABLE_ENTRY_TYPE(lchip, tbl_id)           (TABLE_INFO(lchip, tbl_id).slicetype)
#define TABLE_FIELD_NUM(lchip, tbl_id)            (TABLE_INFO(lchip, tbl_id).field_num)
#define TABLE_FIELD_INFO_PTR(lchip, tbl_id)       (TABLE_INFO(lchip, tbl_id).ptr_fields)
#define TABLE_IOCTL_TYPE(lchip, tbl_id)           (TABLE_INFO(lchip, tbl_id).tbl_type)
#define TABLE_MAX_INDEX(lchip, tbl_id)          (TABLE_INFO(lchip, tbl_id).entry?TABLE_INFO(lchip, tbl_id).entry:TABLE_EXT_INFO(lchip, tbl_id).entry)
#define TABLE_ENTRY_SIZE(lchip, tbl_id)         (TABLE_INFO(lchip, tbl_id).byte)
#define TABLE_ENTRY_OFFSET(lchip, tbl_id)       (TABLE_INFO(lchip, tbl_id).entry_offset)
#define TABLE_DATA_BASE(lchip, tbl_id, index)   (TABLE_INFO(lchip, tbl_id).entry?TABLE_INFO(lchip, tbl_id).addrs[index]:TABLE_EXT_INFO(lchip, tbl_id).addrs[index])
#define TABLE_NAME(lchip, tbl_id)                (p_drv_master[lchip]->p_tbl_name[p_drv_master[lchip]->p_tbl_mapping[tbl_id]].ptr_tbl_name)
#define FIELD_NAME(lchip, tbl_id, field_id)      (p_drv_master[lchip]->p_tbl_name[p_drv_master[lchip]->p_tbl_mapping[tbl_id]].fields_name[field_id].ptr_field_name)

#define TABLE_EXT_INFO(lchip, tbl_id)             (p_drv_master[lchip]->p_tbl_ext_info[p_drv_master[lchip]->p_tbl_mapping[tbl_id]])
#define TABLE_EXT_INFO_PTR(lchip, tbl_id)         (TABLE_EXT_INFO(lchip, tbl_id).ptr_ext_info)
#define TABLE_EXT_INFO_TYPE(lchip, tbl_id)        (TABLE_EXT_INFO_PTR(lchip, tbl_id)->ext_content_type)
#define TABLE_EXT_INFO_CONTENT_PTR(lchip, tbl_id) (TABLE_EXT_INFO_PTR(lchip, tbl_id)->ptr_ext_content)
#define TABLE_OP_TYPE(lchip, tbl_id)           (TABLE_INFO(lchip, tbl_id).optype)
#define TCAM_LPM_LKP2_ENTRY_NUM(lchip, tbl_id)    (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_lpmlkp2_entry_num)
#define TABLE_EXT_TYPE(lchip, tbl_id)        (TABLE_EXT_INFO_PTR(lchip, tbl_id)->ext_type)

#if (SDK_WORK_PLATFORM == 1)
#define TABLE_ADDR_NUM(lchip, tbl_id)             ((TABLE_INFO(lchip, tbl_id).addr_num)/2)
#else
#define TABLE_ADDR_NUM(lchip, tbl_id)             (TABLE_INFO(lchip, tbl_id).addr_num)
#endif

#define BURST_IO_WRITE  0x1
#define BURST_IO_READ   0x1
#define BURST_IO_MASK   0x2

 /*#define TABLE_FIELD_SEG_PTR(seg_id)     (TABLE_INFO(lchip, tbl_id).ptr_fields.)*/

#define CHK_IS_REGISTER(lchip, tbl_id)\
    ((tbl_id < MaxTblId_t)&&(TABLE_MAX_INDEX(lchip, tbl_id) == 1))\

#define CHK_TABLE_ID_VALID(lchip, tbl_id)\
    (tbl_id < MaxTblId_t)\

#define TCAM_EXT_INFO_PTR(lchip, tbl_id)                   (TCAM_TYPE_EXT (TABLE_EXT_INFO_PTR(lchip, tbl_id)->ptr_ext_content))
#define TCAM_MASK_BASE_LPM(lchip, tbl_id, addroffset)      (TCAM_EXT_INFO_PTR(lchip, tbl_id)->hw_mask_base[addroffset])
#define TCAM_KEY_TYPE(lchip, tbl_id)                       (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_type)
#define TCAM_KEY_MODULE(lchip, tbl_id)                     (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_module)
#define TCAM_KEY_BLOCK_ID(lchip, tbl_id, i)                (TCAM_EXT_INFO_PTR(lchip, tbl_id)->blk_id[i])
#define TCAM_KEY_DRV_TYPE(lchip, tbl_id)                   (TCAM_EXT_INFO_PTR(lchip, tbl_id)->drv_tcam_type)
#define TCAM_KEY_SIZE(lchip, tbl_id)            (TCAM_EXT_INFO_PTR(lchip, tbl_id)->key_size)
#define TCAM_BITMAP(lchip, tbl_id)                         (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_bitmap)
#define TCAM_DATA_BASE(lchip, tbl_id, blk_id, addroffset)  (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_hw_data_base[blk_id][addroffset])
#define TCAM_MASK_BASE(lchip, tbl_id, blk_id, addroffset)  (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_hw_mask_base[blk_id][addroffset])
#define TCAM_ENTRY_NUM(lchip, tbl_id, blk_id)              (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_entry_num[blk_id])
#define TCAM_START_INDEX(lchip, tbl_id, blk_id) (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_entry_start_index[blk_id])
#define TCAM_END_INDEX(lchip, tbl_id, blk_id)              (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_entry_end_index[blk_id])
#define TCAM_TABLE_SW_BASE(lchip, tbl_id, blk_id)            (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.tcam_mem_sw_data_base[blk_id])

#define  TCAM_TABLE_START(lchip, tbl_id, i)            (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.start_index[i])
#define  TCAM_TABLE_END(lchip, tbl_id, i)              (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.end_index[i])
#define  TCAM_TABLE_BLK_ID(lchip, tbl_id, i)           (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.block_id[i])
#define  TCAM_TABLE_BLK_NUM(lchip, tbl_id)             (TCAM_EXT_INFO_PTR(lchip, tbl_id)->tcam_alloc_info.block_num)

#define DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)                    (DYNAMIC_TYPE_EXT (TABLE_EXT_INFO_PTR(lchip, tbl_id)->ptr_ext_content))
#define DYNAMIC_ACCESS_MODE(lchip, tbl_id)                     (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_access_mode)
#define DYNAMIC_BITMAP(lchip, tbl_id)                          (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.dynamic_mem_bitmap)
#define DYNAMIC_DATA_BASE(lchip, tbl_id, blk_id, addroffset)   (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.dynamic_mem_hw_data_base[blk_id][addroffset])
#define DYNAMIC_ENTRY_NUM(lchip, tbl_id, blk_id)               (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.dynamic_mem_entry_num[blk_id])
#define DYNAMIC_START_INDEX(lchip, tbl_id, blk_id)             (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.dynamic_mem_entry_start_index[blk_id])
#define DYNAMIC_END_INDEX(lchip, tbl_id, blk_id)               (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.dynamic_mem_entry_end_index[blk_id])
#define DYNAMIC_MEM_OFFSET(lchip, tbl_id, blk_id)              (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.dynamic_mem_block_offset[blk_id])

#define DYNAMIC_TABLE_START(lchip, tbl_id, i)         (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.start_index[i])
#define DYNAMIC_TABLE_END(lchip, tbl_id, i)           (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.end_index[i])
#define DYNAMIC_TABLE_BLK_ID(lchip, tbl_id, i)        (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.block_id[i])
#define DYNAMIC_TABLE_BLK_NUM(lchip, tbl_id)          (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.block_num)

#define DYNAMIC_MEM_SIZE(lchip, tbl_id)                  (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.mem_size)
#define DYNAMIC_TABLE_WORDS(lchip, tbl_id)             ((DYNAMIC_ACCESS_MODE(lchip, tbl_id)&0xFF))
#define DYNAMIC_TABLE_UNIT_NUM(lchip, tbl_id)         (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.unit_num)
#define DYNAMIC_TABLE_UNIT_SIZE(lchip, tbl_id)        (DYNAMIC_EXT_INFO_PTR(lchip, tbl_id)->dynamic_mem_allocate_info.unit_size)
#define DYNAMIC_TABLE_RW_INDEX(lchip, tbl_id, index)   ((index/DYNAMIC_TABLE_UNIT_NUM(lchip, tbl_id))*DYNAMIC_TABLE_UNIT_NUM(lchip, tbl_id))


/*Only Model start*/
#define DYNAMIC_UNIT_NUM(lchip, tbl_id)                      (((DYNAMIC_ACCESS_MODE(lchip, tbl_id)>>DYNAMIC_ACCESS_UNIT_NUM_SHIFT)&0xFF)\
                                                            ?:(DYNAMIC_MEM_SIZE(lchip, tbl_id)/TABLE_ENTRY_SIZE(lchip, tbl_id)))
#define DYNAMIC_UNIT_SIZE(lchip, tbl_id)                     (((DYNAMIC_ACCESS_MODE(lchip, tbl_id)>>DYNAMIC_ACCESS_UNIT_SIZE_SHIFT)&0xFF)*DRV_BYTES_PER_WORD \
                                                                ?:(DYNAMIC_MEM_SIZE(lchip, tbl_id)/DYNAMIC_UNIT_NUM(lchip, tbl_id)))
#define DYNAMIC_ACCESS_INDEX(lchip, tbl_id, index)           ((index/DYNAMIC_UNIT_NUM(lchip, tbl_id))*DYNAMIC_UNIT_NUM(lchip, tbl_id))


/*Model end*/


#define DRV_TBL_INS_OFFSET(index)                            ((index>>24)&0xFF)
#define DRV_TBL_INS_INDEX(index)                             (index&0xFFFFFF)
#define DRV_TBL_ALL_INS_MASK                                 0x80000000

/* check Table Id valid */
#define DRV_TBL_ID_VALID_CHECK(lchip, tbl_id) \
if ((tbl_id) >= (MaxTblId_t))\
{\
    DRV_DBG_INFO("\nERROR! INVALID TblID! TblID: %d, file:%s line:%d function:%s\n",tbl_id, __FILE__,__LINE__,__FUNCTION__);\
    return DRV_E_INVALID_TBL;\
}

/* check if Table is empty */
#define DRV_TBL_EMPTY_CHECK(lchip, tbl_id) \
if (TABLE_MAX_INDEX(lchip, tbl_id) == 0)\
{\
    DRV_DBG_INFO("\nERROR! Operation on an empty table! TblID: %d, Name:%s, file:%s line:%d function:%s\n",tbl_id, TABLE_NAME(lchip, tbl_id), __FILE__,__LINE__,__FUNCTION__);\
    return DRV_E_INVALID_TBL;\
}

/* check is index of table id is valid */
#define DRV_TBL_INDEX_VALID_CHECK(lchip, tbl_id, index)                                                                      \
if ((1 == TABLE_ADDR_NUM(lchip, tbl_id) && TABLE_MAX_INDEX(lchip, tbl_id) <= index)                                       \
   || (TABLE_ADDR_NUM(lchip, tbl_id) > 1 && !(index&DRV_TBL_ALL_INS_MASK)                                                  \
   && ((TABLE_MAX_INDEX(lchip, tbl_id) <= DRV_TBL_INS_INDEX(index))                                                         \
   || (DRV_TBL_INS_OFFSET(index) >= TABLE_ADDR_NUM(lchip, tbl_id)))))                                                      \
{\
    DRV_DBG_INFO("\nERROR! Index-0x%x exceeds the max_index 0x%x! TblID: %d, Name:%s, file:%s line:%d function:%s\n", \
                   index, TABLE_MAX_INDEX(lchip, tbl_id), tbl_id, TABLE_NAME(lchip, tbl_id), __FILE__,__LINE__,__FUNCTION__);\
    return DRV_E_INVALID_INDEX;\
}

enum drv_io_tcam_type_e
{
    DRV_IO_TCAM_TYPE_FLOW,
    DRV_IO_TCAM_TYPE_LPM,
    DRV_IO_TCAM_TYPE_NAT,
    DRV_IO_TCAM_TYPE_I_ACL,
    DRV_IO_TCAM_TYPE_E_ACL,
    DRV_IO_TCAM_TYPE_I_SCL0,
    DRV_IO_TCAM_TYPE_I_SCL1,
    DRV_IO_TCAM_TYPE_E_SCL,
    DRV_IO_TCAM_TYPE_CID,
    DRV_IO_TCAM_TYPE_QUE,
    DRV_IO_TCAM_TYPE_LTID,
    DRV_IO_TCAM_TYPE_I_LTID = DRV_IO_TCAM_TYPE_LTID,
    DRV_IO_TCAM_TYPE_VMAC,
    DRV_IO_TCAM_TYPE_UDF,
    DRV_IO_TCAM_TYPE_E_LTID,
    DRV_IO_TCAM_TYPE_NUM
};

typedef struct drv_io_tcam_db_s
{
    uint16 blk_shift;
    uint16 tbl_size;
    uint32 tcam_mem_tbl_id;
    uint32 tcam_mem_fld_id;
    uint32 hw_words:8;
    uint32 mem_id:24;

    int32 (*drv_tcam_get_block_info)(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32 *blknum, uint32 *local_idx);

}drv_io_tcam_db_t;

typedef struct
{
    uint32 key_index;
    uint32 tbl_id;
    uint8 is_read;
    uint8 cam_num;
    uint8 is_left;     /*for cid acc*/
    uint8 is_high;     /*for cid acc*/
    void* data;
    uint8  is_cam;
    uint8  cam_step ;
    uint8  conflict;  /*for asic lookup result*/
    uint8  valid;     /*for asic lookup result*/
    uint32 cam_table;
    uint8   hash_type;
    uint8  tcam_hit;
    uint8 oper_bmp;/* only for chip from AT */
}drv_cpu_acc_prepare_info_t;


typedef int32 (*DRV_ACC_CB)(uint8 lchip, uint8 module, drv_acc_in_t* in, drv_acc_out_t* out);
typedef int32 (*DRV_IOCTL_CB)(uint8 lchip, uint32 , uint32 , uint8 , uint32* val);
typedef int32 (*DRV_MASK_WRITE_CB)(uint8 lchip, uint32 , uint32 , uint32, uint8 , uint32* val);
typedef int32 (*EUNIT_LOCK_CB)(uint8 lchip, uint8 eunit_lock_type, uint8 status);
typedef int32 (*DRV_FDB_ACC_PRE_CB)(uint8 lchip, drv_acc_in_t* , uint32* );
typedef int32 (*DRV_CPU_ACC_PRE_CB)(uint8 lchip, drv_acc_in_t* , drv_cpu_acc_prepare_info_t* );
typedef int32 (*DRV_FDB_ACC_RST_CB)(uint8 lchip,drv_acc_in_t*,uint32* rst, drv_acc_out_t* out);

typedef enum drv_eunit_lock_type_e
{
    DRV_EUNIT_LOCK_FIBACC = 0,

    DRV_EUNIT_LOCK_MAX = 7
}drv_eunit_lock_type_t;


typedef struct drv_lpm_block_s
{
   uint32 block_id:2;
   uint32 offset:14;
   uint32 max_index:16;
}drv_lpm_block_t;

struct drv_chip_info_s
{
    uint8 core_id;
    uint8 pp_id;
    uint8 def_bmp[2];     /* 0:write/remove; 1: read */
};
typedef struct drv_chip_info_s drv_chip_info_t;

struct drv_master_s
{
    uint8 access_type;
    uint8 plaform_type;
    uint8 workenv_type;
    uint8 host_type;
    uint8 burst_en;
    uint8 wb_status;
    uint8 g_lchip;
    uint8 init_done;
    uint8 sdb_type;
    void* p_ser_master;
    uint8 dev_type;
    uint8 dev_sub_type;
    uint8 pp_base;
    uint8 met_ext_mode;/*AT*/
    uint8 dp_bmp[2][2];
    uint8 pp_bmp[4];
    uint8 core_bmp[2][2];
    uint8 oper_mask[MEM_TYPE_PER_MAX];
    uint8 core_pp_num;

    sal_mutex_t* p_entry_mutex;
    sal_mutex_t* fib_acc_mutex;
    sal_mutex_t* cpu_acc_mutex;
    sal_mutex_t* ipfix_acc_mutex;
    sal_mutex_t* cid_acc_mutex;
    sal_mutex_t* mpls_acc_mutex;
    sal_mutex_t* gemport_acc_mutex;
    sal_mutex_t* p_tcam_write_mutex;
    sal_mutex_t* p_sup1_entry_mutex;

    sal_mutex_t* p_mep_mutex;
    sal_mutex_t* p_pci_mutex;
    sal_mutex_t* p_i2c_mutex;
    sal_mutex_t* p_hss_mutex;
    sal_mutex_t* p_mmap_mutex;


    uint32 *p_enum_value;
    uint32 *p_tcam_map;
    tables_info_t* p_tbl_info;
    tables_ext_info_t* p_tbl_ext_info;
    tables_name_t* p_tbl_name;
    uint16* p_tbl_mapping;
    drv_mem_t* p_mem_info;
    drv_ecc_data_t drv_ecc_data;
    drv_io_callback_fun_t drv_io_api;  /* driver IO callback function */
    drv_io_tcam_db_t* drv_io_tcam_db;
    void* dev_virt_addr;

    int32 (*drv_chip_read)(uint8 lchip, uint64 offset, uint32 len, uint32* p_value);
    int32 (*drv_chip_write)(uint8 lchip, uint64 offset, uint32 len, uint32* p_value);

    int32 (*drv_chip_read_ext)(uint8 lchip, uint64 addr, uint32 len, uint32* p_value, uint8 offset, uint16 real_len);
    int32 (*drv_chip_write_ext)(uint8 lchip, uint64 addr, uint32 len, uint32* p_value);
    int32 (*drv_get_mcu_lock_id)(uint8 lchip, tbls_id_t tbl_id, uint8* p_mcu_id, uint32* p_lock_id);
    int32 (*drv_get_mcu_addr)(uint8 mcu_id, uint32* mutex_data_addr, uint32* mutex_mask_addr);

    int32 (*drv_mem_get_edram_bitmap)(uint8 lchip, uint8 sram_type, uint32* bit);

    int32 (*drv_chip_read_hss15g)(uint8 lchip, uint8 hssid, uint32 addr, uint16* p_data);
    int32 (*drv_chip_write_hss15g)(uint8 lchip, uint8 hssid, uint32 addr, uint16 data);

    int32 (*drv_chip_read_hss28g)(uint8 lchip, uint8 hssid, uint32 addr, uint16* p_data);
    int32 (*drv_chip_write_hss28g)(uint8 lchip, uint8 hssid, uint32 addr, uint16 data);

    int32 (*drv_chip_read_hss)(uint8 lchip, uint32 grp_id, uint32 addr, void* p_data);
    int32 (*drv_chip_write_hss)(uint8 lchip, uint32 grp_id, uint32 addr, void* p_data);

    DRV_ACC_CB drv_acc_cb[DRV_ACC_HASH_MODULE_NUM];
    DRV_IOCTL_CB ioctl_cb[DRV_TBL_TYPE_MAX][DRV_IOC_MAX];  /* uint32 tbl_type:3 */
    DRV_FDB_ACC_PRE_CB   fdb_pre_cb[DRV_ACC_MAX_TYPE][2];
    DRV_CPU_ACC_PRE_CB    acc_pre_cb[DRV_ACC_HASH_MODULE_NUM];  /* uint32 tbl_type:3 */
    DRV_FDB_ACC_RST_CB   fdb_rst_cb[DRV_ACC_MAX_TYPE][2];

    drv_mchip_api_t  mchip_api;
    drv_lpm_block_t lpm_block[3][3]; /*[3][-],3 indicate lpm type,  0:not care public or ipsa, 1:public or ipda, 2:priovate or ipsa
                                       [-][3],3 idicaste lpm tcam block num */
    uint16* lpm_index_map[3];

    EUNIT_LOCK_CB eunit_lock_cb;
    uint32 eunit_lock_en :1;
    uint32 rsv :31;

};

typedef enum
{
    DRV_MCU_LOCK_WA_CFG = 0,
    DRV_MCU_LOCK_HSS15G_REG,
    DRV_MCU_LOCK_HSS28G_REG,
    DRV_MCU_LOCK_PCS_RESET,
    DRV_MCU_LOCK_EYE_SCAN_0,
    DRV_MCU_LOCK_EYE_SCAN_1,
    DRV_MCU_LOCK_EYE_SCAN_2,
    DRV_MCU_LOCK_EYE_SCAN_3,
    DRV_MCU_LOCK_EYE_SCAN_4,
    DRV_MCU_LOCK_EYE_SCAN_5,
    DRV_MCU_LOCK_EYE_SCAN_6,
    DRV_MCU_LOCK_EYE_SCAN_7,
    DRV_MCU_LOCK_TXEQ_CFG,
    DRV_MCU_LOCK_RXEQ_CFG,

    DRV_MCU_LOCK_NONE,

    DRV_MCU_LOCK_MAX
}drv_mcu_lock_t;

#define DRV_MAX_CHIP_NUM 32
#define DRV_MAX_PP_NUM 8

extern drv_master_t* p_drv_master[DRV_MAX_CHIP_NUM];
extern drv_chip_info_t g_drv_chip[DRV_MAX_CHIP_NUM];

#define DRV_MCHIP_API(lchip)   (p_drv_master[lchip]->mchip_api)

#define DRV_MCHIP_FTM_API(lchip)   (p_drv_master[lchip]->mchip_api.p_mchip_ftm)
#define DRV_MCHIP_SER_API(lchip)   (DRV_MCHIP_API(lchip).p_mchip_ser)
#define DRV_MCHIP_SDB_API(lchip)   (p_drv_master[lchip]->mchip_api.p_mchip_sdb)

#define DRV_GET_MCU_LOCK_ID (*p_drv_master[lchip]->drv_get_mcu_lock_id)
#define DRV_GET_MCU_ADDR    (*p_drv_master[lchip]->drv_get_mcu_addr)

extern uint8 drv_map_ldev[DRV_MAX_CHIP_NUM];
#define DRV_MAP_LDEV(lchip) (drv_map_ldev[lchip])

extern int32 dal_get_chip_number(uint8* p_num);
extern int32 drv_usw_table_consum_hw_addr_size_per_index(uint8 lchip, tbls_id_t tbl_id, uint32 *hw_addr_size);
extern int32 drv_usw_get_tbl_string_by_id(uint8 lchip, tbls_id_t tbl_id, char* name);
extern int32 drv_usw_get_tbl_id_by_string(uint8 lchip, tbls_id_t* tbl_id, char* name);
extern int32 drv_usw_get_field_string_by_id(uint8 lchip, tbls_id_t tbl_id, fld_id_t field_id, char* name);
extern int32 drv_usw_get_field_id_by_string(uint8 lchip, tbls_id_t tbl_id, fld_id_t* field_id, char* name);
extern int32 drv_usw_get_field_offset(uint8 lchip, tbls_id_t tbl_id, fld_id_t field_id, uint32* w_offset, uint32 *b_offset);
extern int8 drv_usw_table_is_slice1(uint8 lchip, tbls_id_t tbl_id);
extern int32 drv_usw_serdes_lock(uint8 lchip, uint8 hss_type, uint8 is_reg, uint8 is_aet, uint8 core_id);
extern int32 drv_usw_serdes_unlock(uint8 lchip, uint8 hss_type, uint8 is_reg, uint8 is_aet, uint8 core_id);
extern int32 drv_usw_mcu_tbl_lock(uint8 lchip, tbls_id_t tbl_id, uint32 op);
extern int32 drv_usw_mcu_tbl_unlock(uint8 lchip, tbls_id_t tbl_id, uint32 op);
extern int32 drv_usw_mcu_lock(uint8 lchip, uint32 lock_id, uint8 mcu_id);
extern int32 drv_usw_mcu_unlock(uint8 lchip, uint32 lock_id, uint8 mcu_id);
extern int32 drv_usw_chip_sram_tbl_copy(uint8 lchip, tbls_id_t dst_tbl, uint32 dst_idx, tbls_id_t src_tbl, uint32 src_idx);
extern int32 drv_usw_chip_tcam_tbl_copy(uint8 lchip, tbls_id_t dst_tbl, uint32 dst_idx, tbls_id_t src_tbl, uint32 src_idx);
extern int32 drv_usw_table_get_static_hw_addr(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32* hw_addr);
extern int32 drv_usw_table_get_dyn_hw_addr(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32* hw_addr);
extern int32 drv_usw_table_get_tcam_ad_hw_addr(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32* hw_addr);
extern int32 drv_usw_table_get_tcam_ad_hw_addr1(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32* hw_addr);

#endif /*end of _DRV_COMMON_H*/

